package com.nidu.demo.mail.consumer;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.extra.mail.MailUtil;
import cn.hutool.extra.mail.MailAccount;
import com.nidu.demo.common.enums.MailSendStatusEnum;
import com.nidu.demo.mail.model.MailSendEvent;
import com.nidu.demo.mail.gateway.MailAccountGateway;
import com.nidu.demo.mail.gateway.MailLogGateway;
import com.nidu.demo.mail.model.MailLog;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.List;

/**
 * 邮件发送事件处理器
 *
 * @author auto
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class MailSendEventHandler {

    private final MailLogGateway mailLogGateway;
    private final MailAccountGateway mailAccountGateway;

    @Async("mailSendExecutor")
    @EventListener
    public void handleMailSend(MailSendEvent event) {
        Long mailLogId = event.getMailLogId();
        log.info("开始异步发送邮件，邮件日志ID: {}", mailLogId);

        try {
            // 1. 获取邮件日志信息
            MailLog mailLog = mailLogGateway.getById(mailLogId);
            if (mailLog == null) {
                log.error("邮件日志不存在，ID: {}", mailLogId);
                return;
            }

            // 2. 获取邮件账号信息
            com.nidu.demo.mail.model.MailAccount domainAccount = mailAccountGateway.getById(mailLog.getAccountId());
            if (domainAccount == null) {
                log.error("邮件账号不存在，ID: {}", mailLog.getAccountId());
                mailLogGateway.updateSendFail(mailLogId, MailSendStatusEnum.FAILURE.getValue(), "邮件账号不存在");
                return;
            }

            // 3. 构建hutool邮件账号
            MailAccount hutoolAccount = buildHutoolMailAccount(domainAccount);

            // 4. 发送邮件
            String messageId = sendMail(hutoolAccount, mailLog);

            // 5. 更新发送成功状态
            mailLogGateway.updateSendSuccess(mailLogId, MailSendStatusEnum.SUCCESS.getValue(), messageId);
            log.info("邮件发送成功，邮件日志ID: {}, 消息ID: {}", mailLogId, messageId);

        } catch (Exception e) {
            log.error("邮件发送失败，邮件日志ID: {}", mailLogId, e);
            // 更新发送失败状态
            mailLogGateway.updateSendFail(mailLogId, MailSendStatusEnum.FAILURE.getValue(), e.getMessage());
        }
    }

    /**
     * 发送邮件
     */
    private String sendMail(MailAccount account, MailLog mailLog) {
        List<String> toMails = mailLog.getToMails();
        List<String> ccMails = mailLog.getCcMails();
        List<String> bccMails = mailLog.getBccMails();
        String title = mailLog.getTemplateTitle();
        String content = mailLog.getTemplateContent();

        // 构建收件人集合
        Collection<String> toCollection = CollUtil.isNotEmpty(toMails) ? (Collection<String>) toMails : CollUtil.newArrayList();
        Collection<String> ccCollection = CollUtil.isNotEmpty(ccMails) ? (Collection<String>) ccMails : null;
        Collection<String> bccCollection = CollUtil.isNotEmpty(bccMails) ? (Collection<String>) bccMails : null;

        // 使用hutool发送邮件
        if (ccCollection != null || bccCollection != null) {
            // 有抄送或密送
            return MailUtil.send(account, toCollection, ccCollection, bccCollection, title, content, true);
        } else {
            // 只有收件人
            return MailUtil.send(account, CollUtil.join(toCollection, ","), title, content, true);
        }
    }

    /**
     * 构建hutool邮件账号
     */
    private MailAccount buildHutoolMailAccount(com.nidu.demo.mail.model.MailAccount domainAccount) {
        MailAccount account = new MailAccount();
        account.setHost(domainAccount.getHost());
        account.setPort(domainAccount.getPort());
        account.setAuth(true);
        account.setUser(domainAccount.getUsername());
        account.setPass(domainAccount.getPassword());
        account.setFrom(domainAccount.getMail());
        
        // 设置SSL和STARTTLS
        if (Boolean.TRUE.equals(domainAccount.getSslEnable())) {
            account.setSslEnable(true);
        }
        if (Boolean.TRUE.equals(domainAccount.getStarttlsEnable())) {
            account.setStarttlsEnable(true);
        }
        
        return account;
    }
}
